/****************************************************
 * Copyright (C) 2021.07
 * All rights reserved
 * Author: shelman
 * Date: 2021.07.10
 * Abstracts:
 *  A helper class to operate SQLite3
 * **************************************************/

#ifndef SQLITE3HELPER_H
#define SQLITE3HELPER_H

#include <string>
#include <vector>
#include <mutex>
#include "export_def.h"


struct sqlite3;

class API_EXPORT_DECL Sqlite3Helper
{
public:
    /***********************************************************************
     * function: constructor
     * *********************************************************************/
    explicit Sqlite3Helper();

    /**********************************************************************
     * function: destructor
     * *********************************************************************/
    virtual ~Sqlite3Helper();

    /**********************************************************************
     * function: create or open database
     * input params:
     *      strDbName: database name
     * return:
     *      bool: operation result, true -- success, false -- failed
     * *********************************************************************/
    bool createOrOpenDatabase(const std::string& strDbName);

    /**********************************************************************
     * function: close database
     * *********************************************************************/
    void closeDatabase();

    /**********************************************************************
      * function: drop (delete) database
      * input params:
      *      strDbName: database name
      * return:
      *      bool: operation result, true -- success, false -- failed
      * *********************************************************************/
    void dropDatabase(const std::string& strDbName);

    /**********************************************************************
       * function: create table in this data base
       * input params:
       *      strTableName: the table name
       *      strExpression: sql expression
       * return:
       *      bool: operation result, true -- success, false -- failed
       * *********************************************************************/
    bool createTable(const std::string& strTableName, const std::string& strExpression);

    /**********************************************************************
     * function: drop table in this data base
     * input params:
     *      strTableName: the table name
     * return:
     *      bool: operation result, true -- success, false -- failed
     * *********************************************************************/
    bool dropTable(const std::string& strTableName);

    /**********************************************************************
     * function: insert records into the table
     * input params:
     *      trTableName: the table name
     *      vtNames: record names
     *      vtValues: record values
     * return:
     *      bool: operation result, true -- success, false -- failed
     * *********************************************************************/
    bool insert(const std::string& strTableName
                , const std::vector<std::string>& vtNames
                , const std::vector<std::string>& vtValues);

    /**********************************************************************
     * function: update records in the table
     * input params:
     *      strTableName: the table name
     *      vtNames: record names
     *      vtValues: record values
     *      strExpression: sql expression
     * return:
     *      bool: operation result, true -- success, false -- failed
     * *********************************************************************/
    bool update(const std::string& strTableName
                , const std::vector<std::string>& vtNames
                , const std::vector<std::string>& vtValues
                , const std::string& strExpression);

    /**********************************************************************
     * function: delete record in the table
     * input params:
     *      strTableName: the table name
     *      strExpression: sql expression
     * return:
     *      bool: operation result, true -- success, false -- failed
     * *********************************************************************/
    bool deleteRecord(const std::string& strTableName, const std::string& strExpression);

    /**********************************************************************
     * function: clear all records in the table
     * input params:
     *      strTableName: the table name
     * return:
     *      bool: operation result, true -- success, false -- failed
     * *********************************************************************/
    bool clearRecords(const std::string& strTableName);

    /**********************************************************************
     * function: get values in the table
     * input params:
     *      strTableName: the table name
     *      strExpression: sql expression
     *		iColumn: column of single row info
     * output params:
     *      qstrlstValues: query out the values
     * return:
     *      size_t: rows of query result
     * *********************************************************************/
    size_t getValues(const std::string& strTableName, const std::string& strExpression
                     , size_t iColumn, std::vector<std::string>& vtValues);

    /**********************************************************************
     * function: get values by user sql statement, eg. slect * from {table name} where {limit express}
     * input params:
     *      strStatement: user sql statement sql
     *      iColumn：column of single row info
     * output params:
     *      vtResults: query out the values
     * return:
     *      size_t: rows of query result
     * *********************************************************************/
    size_t getValuesByStatement(const std::string& strStatement, size_t iColumn, std::vector<std::string>& vtResults);

    /**********************************************************************
     * function: get row count in the table
     * input params:
     *      strTableName: the table name
     * return:
     *      size_t: total count in the table
     * *********************************************************************/
    size_t getRowCount(const std::string& strTableName);

    /**********************************************************************
     * function: backup record to new database
     * input params:
     *      strNewDbName: the new database name
     * return:
     *      bool: operation result, true -- success, false -- failed
     * *********************************************************************/
    bool backup(const std::string& strNewDbName);

private:
    /**********************************************************************
     * function: exec the sql statement
     * input params:
     *      strSqlStatement: the sql statement sentence
     * return:
     *      bool: operation result, true -- success, false -- failed
     * *********************************************************************/
    bool exec(const std::string& strSqlStatement);

private:
    sqlite3* m_pSqlite3Instance = nullptr; // sqlite3 instance pointer
    std::string m_strDbName = ""; // database name
    std::mutex m_mt4Business; // business lock
};


#endif // SQLITE3HELPER_H
